# -*- coding: utf-8 -*-

# Copyright: (c) 2007 by Jarek Zgoda, <jzgoda@o2.pl>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307, USA.

"""Main service access class"""

__revision__ = '$Id: lastfmsvc.py 35 2007-04-24 19:12:18Z jarek.zgoda $'

import md5
from xml.sax.saxutils import escape as xml_escape
import xmlrpclib

import common

class LastFMService(object):
    """
    This class allows performing common operations on artist/album/track
    metadata on LastFM.
    It is highly strange, but it uses XML-RPC to communicate with service
    backend.
    All string data is expected to be unicode objects.
    """

    def __init__(self, username, password, host=common.WS_URL):
        self.username = xml_escape(username)
        self.password = md5.new(password).hexdigest()
        endpoint_url = 'http://%s/1.0/rw/xmlrpc.php' % host
        self.server = xmlrpclib.ServerProxy(endpoint_url)

    def remove_from_listened(self, artist, track):
        """
        Removes track from (recently, according to LastFM staff) listened
        songs list.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.removeRecentlyListenedTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
        )

    def love(self, artist, track):
        """
        Adds the track to "loved radio" list.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.loveTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
        )

    def remove_from_loved(self, artist, track):
        """
        Removes track from "loved radio" list.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.unLoveTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
        )

    def ban(self, artist, track):
        """
        Bans the track from any radio station on LastFM.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.banTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
        )

    def remove_from_banned(self, artist, track):
        """
        Removes the track from the list of banned tracks on LastFM.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.unBanTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
        )

    def recommend_artist(self, username, message, artist):
        """
        Sends a recommendation of the artist to other LastFM entity
        (user or group).
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.recommendArtist(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(username),
            xml_escape(message),
        )

    def recommend_album(self, username, message, artist, album):
        """
        Sends a recommendation of the album to other LastFM entity
        (user or group).
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.recommendAlbum(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(album),
            xml_escape(username),
            xml_escape(message),
        )

    def recommend_track(self, username, message, artist, track):
        """
        Sends a recommendation of the track to other LastFM entity
        (user or group).
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.recommendTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
            xml_escape(username),
            xml_escape(message),
        )

    def tag_artist(self, tags, artist, mode):
        """
        Updates tags for artist. Depending on mode parameter (either "set" or
        "append") the tags replace existing tags or are appended to existing
        tags.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.tagArtist(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            tags,
            mode,
        )

    def tag_album(self, tags, artist, album, mode):
        """
        Updates tags for album. Depending on mode parameter (either "set" or
        "append") the tags replace existing tags or are appended to existing
        tags.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.tagAlbum(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(album),
            tags,
            mode,
        )

    def tag_track(self, tags, artist, track, mode):
        """
        Updates tags for track. Depending on mode parameter (either "set" or
        "append") the tags replace existing tags or are appended to existing
        tags.
        """
        challenge = common.get_challenge_string()
        user_hash = common.get_challenge_hash(self.password, challenge)
        self.server.tagTrack(
            self.username,
            challenge,
            user_hash,
            xml_escape(artist),
            xml_escape(track),
            tags,
            mode,
        )
